home *** CD-ROM | disk | FTP | other *** search
- Subject: GR - A Game Regulator
- Reply-To: mcooper@usc-oberon.arpa
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 4, Issue 113
- Submitted by: talcott!usc-oberon.ARPA:mcooper
-
- #!/bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #!/bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # README
- # Makefile
- # gr.control
- # gr.c
- # gr.h
- # logfile.c
- # This archive created: Mon May 5 13:14:10 1986
- # By: Michael A. Cooper (USC Computing Services, Los Angeles)
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'README'" '(1915 characters)'
- if test -f 'README'
- then
- echo shar: over-writing existing file "'README'"
- fi
- cat << \SHAR_EOF > 'README'
-
- G R - A G A M E R E G U L A T O R
-
- Revision 1.16
-
-
- GR is used to regulate game playing. It checks various system
- facts such as the number of logged in users, and the system load average
- against a central control file to determine whether it is okay to play
- a requested game. It also lets you select a priority (see setpriority(2))
- at which the game will run. See the (enclosed) manual for more details.
-
- GR was formerly called "gsh" from which the base code was written
- at Reed College by a person who wishes to remain anonymous. I "adopted"
- it and have extensively modified the code.
-
- We are currently running GR on 4 of our VAX 750's running 4.2BSD.
- I suspect that the code should run without problems under 4.3BSD. As for
- System V, I'm sure some minimal modifications will have to be made, but
- as yet, I have not tried porting it.
-
- To install GR, edit gr.h and Makefile to tailor to your system.
- The comments supplied therein, should suffice. Then run "make gr" to
- compile GR. You should have no errors. Now edit the "gr.control" file
- to set your local system parameters. Next run "make create" to
- create the appropriate directory and support files. Run "make dolink"
- if you wish to have most of the standard 4.2 games put under the regulator;
- otherwise, you can link them by hand.
-
- I'd appreciate any bugs/comments you wish to pass along.
-
- Mike Cooper
-
-
- +-----------------------------------------------------------------------------+
- | Michael Cooper UUCP: ...!{uscvax, sdcrdcf, scgvaxd, |
- | University Computing Services engvax, smeagol}!usc-oberon!mcooper |
- | University of Southern Cal. BITNET: mcooper@uscvaxq, mcooper@jaxom |
- | Los Angeles, Ca. 90089-0251 ARPA: mcooper@usc-oberon.arpa, |
- | (213) 743-3462 mcooper@usc-eclc.arpa |
- +-----------------------------------------------------------------------------+
- SHAR_EOF
- echo shar: extracting "'Makefile'" '(1506 characters)'
- if test -f 'Makefile'
- then
- echo shar: over-writing existing file "'Makefile'"
- fi
- cat << \SHAR_EOF > 'Makefile'
- #
- # Makefile for Game Regulator.
- #
- # $Header: Makefile,v 1.1 86/05/05 13:13:34 mcooper Exp $
- #
-
- #
- # GAMEDIR - This is where the symbolic links are to be placed.
- # Should be /usr/games.
- #
- GAMEDIR = /usr/games
-
- #
- # HIDEDIR - Name of directory to hide the actual executables
- #
- HIDEDIR = $(GAMEDIR)/.hide
-
- #
- # GROUP - This group has read/execute permissions on HIDEDIR and owns
- # the Game Regulator which is setgid to GROUP.
- #
- GROUP = play
-
- #
- # NAME - Name of Game Regulator in GAMEDIR. I have it set to ".gr"
- # so it doesn't show up with ls(1) by default.
- #
- NAME = .gr
-
- #
- # GAMES - The games in the original GAMEDIR to be put under regulation.
- #
- GAMES = adventure backgammon btlgammon canfield chess cribbage fish\
- hangman mille monop rain rogue sail snake teachgammon trek \
- worm worms wump zork
-
- OBJS = gr.o logfile.o
-
- gr: $(OBJS)
- cc -s $(OBJS) -o gr
-
- dbx: $(OBJS)
- cc -g $(OBJS) -o gr -llocal
-
- .c.o:
- cc -c $*.c
-
- $(OBJS): gr.h
-
- install: gr
- install -m 2751 -g $(GROUP) gr $(GAMEDIR)/$(NAME)
-
- create:
- -mkdir $(HIDEDIR)
- chgrp $(GROUP) $(HIDEDIR)
- chmod 770 $(HIDEDIR)
- cp gr.control $(GAMEDIR)/lib
- touch $(GAMEDIR)/lib/gr.log
- chgrp $(GROUP) $(GAMEDIR)/lib/gr.control $(GAMEDIR)/lib/gr.log
- chmod 664 $(GAMEDIR)/lib/gr.control $(GAMEDIR)/lib/gr.log
-
- dolink: dolink.sh
- sed s#HIDEDIR#$(HIDEDIR)# dolink.sh |\
- sed s#GAMEDIR#$(GAMEDIR)# |\
- sed s#NAME#$(NAME)# > dolink
- chmod +x dolink
- dolink $(GAMES)
-
- clean:
- rm -f *.o log dolink
-
- shar:
- shar README Makefile gr.control *.[ch] > shar.out
- SHAR_EOF
- echo shar: extracting "'gr.control'" '(582 characters)'
- if test -f 'gr.control'
- then
- echo shar: over-writing existing file "'gr.control'"
- fi
- cat << \SHAR_EOF > 'gr.control'
- #
- # Game Regulator Control File
- #
- # Note - The last line contains the default parameters for any file NOT listed.
- #
- # Name - Name of game in /usr/games. (string)
- # Load - Maximum load average. (floating point)
- # Users - Maximum number of users. (integer)
- # Priority - Priority game will run at.
- # See setpriority(2). (integer)
- #
- # Maximum
- # Name Load Users Priority
- #--------------------------------------
- rogue 4.0 8 0
- arogue 4.0 8 0
- srogue 4.0 8 0
- urogue 4.0 8 0
- ourogue 4.0 8 0
- hack 4.0 8 5
- sail 4.0 8 0
- empire 4.0 8 0
- default 5.0 8 0
- SHAR_EOF
- echo shar: extracting "'gr.c'" '(5975 characters)'
- if test -f 'gr.c'
- then
- echo shar: over-writing existing file "'gr.c'"
- fi
- cat << \SHAR_EOF > 'gr.c'
- #ifndef lint
- static char *RCSid = "$Header: gr.c,v 1.16 86/04/26 17:30:53 mcooper Exp $";
- #endif
-
- /*
- *------------------------------------------------------------------
- *
- * $Source: /usr/src/local/gr/RCS/gr.c,v $
- * $Revision: 1.16 $
- * $Date: 86/04/26 17:30:53 $
- * $State: Exp $
- * $Author: mcooper $
- * $Locker: mcooper $
- *
- *------------------------------------------------------------------
- *
- * Michael Cooper (mcooper@usc-oberon.arpa)
- * University Computing Services,
- * University of Southern California,
- * Los Angeles, California, 90089-0251
- * (213) 743-3469
- *
- *------------------------------------------------------------------
- * $Log: gr.c,v $
- * Revision 1.16 86/04/26 17:30:53 mcooper
- * This version adds a new field to the gr.control
- * file that specifies the priority that the game will
- * run at.
- *
- * Revision 1.15 86/03/25 18:50:08 mcooper
- * Added #ifdef LOGFILE.
- *
- * Revision 1.14 86/03/25 15:48:49 mcooper
- * New headers.
- *
- *------------------------------------------------------------------
- */
-
- #include <stdio.h>
- #include <signal.h>
- #include <sys/wait.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <sys/resource.h>
- #include <utmp.h>
- #include <nlist.h>
- #include "gr.h"
-
-
- static int ufd = 0;
- static int max_users;
- static int priority = 0;
- static lfd = 0;
- static double avenrun[3];
- static double max_load;
- static struct utmp buf;
- static struct nlist nl[] = {
- { "_avenrun" },
- { "" },
- };
-
- int was_tod;
- int was_load;
- int was_users;
- char *rindex();
- long time();
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- char *game = rindex(argv[0], '/');
-
- if (game == 0)
- game = argv[0];
- else
- game++; /* Skip the '/' */
- setup(game);
- if(checkfor(NOGAMING))
- exit(2);
- if (tod() || users() || load()) {
- fprintf(stderr, "Sorry, no games now.\n");
- if (was_load)
- fprintf(stderr,
- "The system load is greater than %.2lf.\n",
- max_load);
- if (was_users)
- fprintf(stderr,
- "There are more than %d users logged in.\n",
- max_users);
- if (was_tod)
- fprintf(stderr,
- "Game playing is not permitted between %d00 and %d00 hours on weekdays.\n",
- MORNING, EVENING);
- exit(1);
- }
- #ifdef LOGFILE
- logfile(game);
- #endif
- play(game, argv);
- }
-
- play(game, args)
- char *game;
- char **args;
- {
- int pid;
- char tmp[128];
-
- switch (pid = fork()) {
- case -1:
- fprintf(stderr, "Cannot fork.\n");
- exit(1);
- case 0:
- strcpy(tmp, HIDEDIR);
- strcat(tmp, "/");
- strcat(tmp, game);
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGTSTP, SIG_DFL);
- setuid(getuid());
- if(setpriority(PRIO_PROCESS, 0, priority) < 0) {
- perror("setpriority");
- exit(1);
- }
- execv(tmp, args);
- perror(tmp);
- exit(1);
- }
- for (;;) {
- sleep(60);
- if (load() || users() || tod()) {
- warn(0);
- sleep(60);
- if (reprieve())
- continue;
- sleep(60);
- if (reprieve())
- continue;
- warn(1);
- sleep(60);
- if (reprieve())
- continue;
- warn(2);
- sleep(60);
- if (reprieve())
- continue;
- blast(pid);
- }
- }
- }
-
- reprieve()
- {
- static char mess[] = "\rYou have a reprieve. Continue playing.\r\n";
-
- if (load() || users() || tod())
- return (0);
- write(2, mess, sizeof(mess));
- return (1);
- }
-
- warn(which)
- int which;
- {
- static char buff[512];
- static char *mesg = "to save your game. If you do not leave\r\n\
- the game within this period, your game will be terminated.\r\n";
- static char *t[3] = {
- "4 minutes ",
- "2 minutes ",
- "1 minute "
- };
-
- if (was_load)
- sprintf(buff, "\rThe system load is greater than %.2lf.\r\n",
- max_load);
- if (was_users)
- sprintf(buff, "\rThere are more than %d users logged in.\r\n",
- max_users);
- if (was_tod)
- sprintf(buff, "\rGame time is over.\r\n");
- strcat(buff, "You have ");
- strcat(buff, t[which]);
- strcat(buff, mesg);
- write(2, buff, strlen(buff));
- }
-
- blast(pid)
- int pid;
- {
- static char mess[] = "\rYour game is forfeit.\r\n";
-
- write(2, mess, sizeof(mess));
- kill(pid, SIGHUP);
- sleep(60);
- kill(pid, SIGKILL);
- }
-
- death(n)
- int n;
- {
- union wait status;
-
- if (wait3(&status, WNOHANG | WUNTRACED, (char *)0) == 0) {
- return;
- }
- if (status.w_stopval == WSTOPPED) {
- signal(SIGTSTP, SIG_DFL);
- kill(getpid(), SIGTSTP);
- signal(SIGTSTP, SIG_IGN);
- return;
- } else
- exit(0);
- }
-
-
- setup(game)
- char *game;
- {
- char tmp[16];
- char lbuf[BUFSIZ];
- int n;
- FILE *list;
-
- if ((ufd = open("/etc/utmp", 0)) < 0) {
- perror("/etc/utmp");
- exit(1);
- }
- if ((lfd = open("/dev/kmem", 0)) < 0) {
- perror("/dev/kmem");
- exit(1);
- }
- nlist("/vmunix", nl);
- if (nl[0].n_type == 0) {
- perror("/vmunix");
- exit(1);
- }
- if ((list = fopen(CONTROL, "r")) == NULL) {
- perror(CONTROL);
- exit(1);
- }
- while (fgets(lbuf, sizeof(lbuf), list)) {
- if(lbuf[0] == COMMENT)
- continue;
- sscanf(lbuf, "%s%lf%d%d",
- tmp, &max_load, &max_users, &priority);
- if (strcmp(tmp, game) == 0)
- break;
- }
- fclose(list);
- signal(SIGCHLD, death);
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGTSTP, SIG_IGN);
- }
-
- load()
- {
- lseek(lfd, (long)nl[0].n_value, 0);
- read(lfd, avenrun, sizeof(avenrun));
- return (was_load = (avenrun[1] >= max_load));
- }
-
- users()
- {
- char tmp[32];
- int count = 0;
- long l = time((long *)0);
- struct stat sbuf;
-
- lseek(ufd, (long)0, 0);
- while (read(ufd, &buf, sizeof(buf)) > 0) {
- if (buf.ut_name[0] != '\0') {
- count++;
- }
- }
- return (was_users = (count > max_users));
- }
-
- tod()
- {
- #ifdef TOD
- long now;
- struct tm *localtime();
- struct tm *ntime;
-
- time(&now);
- ntime = localtime(&now);
- if(ntime->tm_wday == 0 || ntime->tm_wday == 6)
- return(was_tod = FALSE);/* OK on Sat & Sun */
- if(ntime->tm_hour < MORNING || ntime->tm_hour >= EVENING)
- return(was_tod = FALSE);/* OK during non working hours */
-
- return(was_tod = TRUE);
- #endif
- }
-
- checkfor(file)
- char *file;
- {
- char buf[200];
- FILE *fd, *fopen();
-
- if((fd = fopen(file, "r")) != NULL) {
- fprintf(stderr, "Sorry, no games now...\n");
- while(fgets(buf, sizeof(buf), fd))
- fprintf(stderr, buf);
- fclose(fd);
- return(TRUE);
- }
- return(FALSE);
- }
- SHAR_EOF
- echo shar: extracting "'gr.h'" '(1771 characters)'
- if test -f 'gr.h'
- then
- echo shar: over-writing existing file "'gr.h'"
- fi
- cat << \SHAR_EOF > 'gr.h'
- /*
- * $Header: gr.h,v 1.3 86/03/25 15:50:31 mcooper Exp $
- *------------------------------------------------------------------
- *
- * $Source: /usr/src/local/gr/RCS/gr.h,v $
- * $Revision: 1.3 $
- * $Date: 86/03/25 15:50:31 $
- * $State: Exp $
- * $Author: mcooper $
- * $Locker: mcooper $
- *
- *------------------------------------------------------------------
- *
- * Michael Cooper (mcooper@usc-oberon.arpa)
- * University Computing Services,
- * University of Southern California,
- * Los Angeles, California, 90089-0251
- * (213) 743-3469
- *
- *------------------------------------------------------------------
- * $Log: gr.h,v $
- * Revision 1.3 86/03/25 15:50:31 mcooper
- * Moved CONTROL back to normal place in /usr/games/lib.
- *
- * Revision 1.2 86/03/25 15:47:57 mcooper
- * Lines beginning with '#' are comment lines.
- *
- * Revision 1.1 86/02/12 17:49:54 mcooper
- * Initial revision
- *
- *------------------------------------------------------------------
- */
-
- /*
- * TOD - define if you wish to restrict game playing during a certain
- * time of day on weekdays. Use MORNING and EVENING as the time
- * period.
- */
- /*
- #define TOD
- */
- #define MORNING 8 /* stop playing games */
- #define EVENING 17 /* game time starts */
-
- /*
- * HIDEDIR - directory where the actual games are kept.
- */
- #define HIDEDIR "/usr/games/.hide"
-
- /*
- * NOGAMING - If this file exists, it's contents are printed out and
- * gaming is not permitted.
- */
- #define NOGAMING "/usr/games/nogames"
-
- /*
- * LOGFILE - Define to file name to log entries in.
- */
- #define LOGFILE "/usr/games/lib/gr.log"
-
- /*
- * CONTROL - Master control file.
- */
- #define CONTROL "/usr/games/lib/gr.control"
-
- /*
- * Misc. defines - Leave this alone!
- */
- #define TRUE 1
- #define FALSE 0
- #define COMMENT '#'
- SHAR_EOF
- echo shar: extracting "'logfile.c'" '(1757 characters)'
- if test -f 'logfile.c'
- then
- echo shar: over-writing existing file "'logfile.c'"
- fi
- cat << \SHAR_EOF > 'logfile.c'
- #ifndef lint
- static char *RCSid = "$Header: logfile.c,v 1.3 86/03/25 15:44:35 mcooper Exp $";
- #endif
-
- /*
- *------------------------------------------------------------------
- *
- * $Source: /usr/src/local/gr/RCS/logfile.c,v $
- * $Revision: 1.3 $
- * $Date: 86/03/25 15:44:35 $
- * $State: Exp $
- * $Author: mcooper $
- * $Locker: mcooper $
- *
- *------------------------------------------------------------------
- *
- * Michael Cooper (mcooper@usc-oberon.arpa)
- * University Computing Services,
- * University of Southern California,
- * Los Angeles, California, 90089-0251
- * (213) 743-3469
- *
- *------------------------------------------------------------------
- * $Log: logfile.c,v $
- * Revision 1.3 86/03/25 15:44:35 mcooper
- * more of same.
- *
- * Revision 1.2 86/03/25 15:35:43 mcooper
- * New headers...
- *
- *------------------------------------------------------------------
- */
-
- /*
- * logfile() -- log who is playing. If LOGFILE is defined (in gr.c)
- * then this function keeps track of users who play.
- */
-
-
- #include <stdio.h>
- #include <pwd.h>
- #include "gr.h"
-
- #ifdef LOGFILE
- struct passwd *pw;
- struct passwd *getpwuid();
-
- logfile(msg)
- char *msg;
- {
- char *fprintf();
- char *strcmp();
- char *getlogin();
- char *time(), *ctime();
- char buf[80];
- char *str;
- char *user;
- double now;
- int diff = 0;
- FILE *fd, *fopen();
-
- if ((pw = getpwuid(getuid())) != NULL)
- user = pw->pw_name;
- else
- user = "(unknown)";
-
- if((str = getlogin()) != NULL)
- if(strcmp(str, user) != 0) {
- diff = 1;
- sprintf(buf, "(%s)", str);
- }
-
- time(&now);
-
- if((fd = fopen(LOGFILE, "a")) != NULL){
- fprintf(fd, "%-10s%-12s%-7s%10.24s [ %s ]\n",
- user,
- diff ? buf : "",
- rindex(ttyname(0), '/') + 1,
- ctime(&now),
- msg);
- fclose(fd);
- }
- }
- #endif
- SHAR_EOF
- # End of shell archive
- exit 0
-
-
-